package src.ai.utils;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.istack.internal.logging.Logger;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.io.StringReader;
import java.util.*;

/**
 * 操作Json数据工具类  
 * @author lty
 * @since 2024-5-1
 */
public class JsonUtil {

    private static Logger logger = Logger.getLogger(JsonUtil.class);

    /**
     * 高性能反序列化方法
     * 使用 JsonFactory 创建了一个 JsonParser，然后通过逐步读取 JSON 令牌的方式来解析 JSON 字符串。
     * 这种方法可以有效地处理大型的 JSON 字符串，并且具有较低的内存占用。
     * @param jsonString
     * @throws IOException
     */
    public static Map<String,Object> deserialize(String jsonString) throws IOException {
        JsonFactory factory = new JsonFactory();
        JsonParser parser = factory.createParser(new StringReader(jsonString));
//        String s = new String();
        Map<String,Object> map = new HashMap<>() ;

        while (!parser.isClosed()) {
            JsonToken jsonToken = parser.nextToken();
            if (JsonToken.FIELD_NAME.equals(jsonToken)) {
                String key = parser.getCurrentName();
                parser.nextToken(); // Move to value token
                String value = parser.getValueAsString();

                map.put(key,value);
//                System.out.println(key + ": " + value);
            }
        }
        System.out.println(map);
        return map;
    }

    /**
     * 将Json对象字符串转化为Map对象  
     * @param jsonStr JSON字符串  
     * @return 转换成功返回Map对象，失败则返回null  
     */
    public static Map<String, String> JsonToMap(String jsonStr) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, String> params = objectMapper.readValue(jsonStr,Map.class);
            return params;
        } catch (Exception e) {
//            logger.error("JsonToMap Error " + jsonStr, e);
            return null;
        }
    }

    /**
     * 将Json对象字符串转化为Map<String, Object>对象
     * 使用 new TypeReference<Map<String, Object>>() {} 来保留了键和值的类型信息。
     * 这意味着 readValue 方法将 JSON 字符串直接转换为具有正确键和值类型的 Map 对象，避免了类型转换的需要。
     * @param jsonStr JSON字符串  
     * @return 转换成功返回Map对象，失败则返回null  
     */
    public static Map<String, Object> readJson2Map(String jsonStr) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> map = objectMapper.readValue(jsonStr, new TypeReference<Map<String, Object>>() {});
        return map;
    }

    /**
     * 将Json对象字符串转化为JavaBean类对象  
     * @param jsonStr JSON字符串  
     * @param clazz 类类型  
     * @return 转换成功返回JavaBean类对象，失败则返回null  
     */
    public static <T> T readJson2Bean(String jsonStr,Class<T> clazz) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            T t = objectMapper.readValue(jsonStr,clazz);
            return t;
        } catch (Exception e) {
//            logger.error("readJson2Bean Error " + jsonStr, e);
            return null;
        }
    }

    /**
     * 将Json对象字符串转化为List<Map>对象  
     * @param jsonStr JSON字符串  
     * @return 转换成功返回Map对象，失败则返回null  
     */
    public static List<HashMap<String, Object>> JsonToMapList(String jsonStr) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            List<HashMap<String, Object>> params = objectMapper.readValue(jsonStr,List.class);
            for (int i = 0; i < params.size(); i++) {
                Map<String, Object> map = params.get(i);
                Set<String> set = map.keySet();
                for (Iterator<String> it = set.iterator(); it.hasNext();) {
                    String key = it.next();
                }
            }
            return params;
        } catch (Exception e) {
//            logger.error("JsonToMap Error " + jsonStr, e);
            return null;
        }
    }

    /**
     * 将传入能够整除2的数量的参数序列化为Json对象  
//     * @param result
     * @return
     */
    public static String WriteToJson(Object... paramObjs){
        try {
            if(paramObjs==null||paramObjs.length==0){
//                logger.error("参数实例为空");
            }
            Map<String,Object> paramMap = new HashMap<String, Object>();
            for(int i=0;i<paramObjs.length;i+=2){
                paramMap.put((String) paramObjs[i], paramObjs[i+1]);
            }
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(paramMap);
        } catch (Exception e) {
            return "";
        }
    }

//    /**
//     * 将传入能够整除2的数量的参数序列化为Json对象，并进行UrlDecode操作
//     * @param result
//     * @return
//     */
//    public static Map<String, String> JsonToMapAndDecode(String result) {
//        Map<String, String> params = JsonToMap(result);
//        for (String key : params.keySet()) {
//            params.put(key, HttpUtils.urlDecode(params.get(key), "UTF-8"));
//        }
//        return params;
//    }

    public static String toJson(Object target){
        String result = null;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            result = objectMapper.writeValueAsString(target);
        } catch (Exception e) {
//            logger.error("convert to Json Str Fail !");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 仅针对于文字识别使用，数据结构为：
     *{words_result=[{"words":"xx"},...], log_id=xx, words_result_num=xx}
     * 只取words
     * @param jsonObject
     * @return
     */
    public static List<String> ocrJsonToList(JSONObject jsonObject) {
        List<String> list = new ArrayList<>();
        JSONArray words_result = (JSONArray) jsonObject.get("words_result");
        int n = jsonObject.getInt("words_result_num");
        for (int i = 0; i < n; i++){
            JSONObject it = (JSONObject) words_result.get(i);
            list.add(it.getString("words"));
        }
        return list;
    }

    /**
     * 仅针对于图片识别使用，数据结构为：
     *{result=[{"score":xx,"root":"xx","keyword":"xx"},...], log_id=xx, result_num=xx}
     * @param jsonObject
     * @return
     */
    public static List<Map<String,Object>> ImagejsonToList(JSONObject jsonObject) {
        List<Map<String,Object>> list = new ArrayList<>();
        JSONArray result = (JSONArray) jsonObject.get("result");
        int n = jsonObject.getInt("result_num");
        for (int i = 0; i < n; i++){
            JSONObject it = (JSONObject) result.get(i);
            Map<String,Object> map = new HashMap<>();
            map.put("score",it.get("score"));
            map.put("root",it.get("root"));
            map.put("keyword",it.get("keyword"));
            list.add(map);
        }
        return list;
    }
}  